package org.caijin.springrabbitMQ.config;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.rabbitmq.client.ConnectionFactory;
import org.springframework.amqp.core.*;

import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

@Configuration
public class RabbitMqConfig {



    //=================== Hello World + Worker Queue ====================

    /**
     * 定义demoQueue队列
     * @return
     */
    @Bean
    public Queue demoString() {
        return new Queue("demoQueue");
    }

    //=================== 死信队列 ====================
    @Bean
    public Queue TestQueue(){
        Map<String, Object> args = new HashMap<>();
        args.put("x-dead-letter-exchange", "deadExchange");
        return new Queue("TestQueue", true, false, false, args);
    }
    @Bean
    public Queue deadQueue(){
        return new Queue("deadQueue");
    }

    @Bean
    public FanoutExchange deadExchange(){
        return new FanoutExchange("deadExchange");
    }

    @Bean
    public Binding deadBinding(){
        return BindingBuilder.bind(deadQueue()).to(deadExchange());
    }


    //=================== Direct Route模式  ====================

    /**
     * 定义quorum队列
     * @return
     */
    @Bean
    public Queue testQuorum() {
        Map<String, Object> args = new HashMap<String, Object>();
        args.put("x-queue-type", "quorum");
        return new Queue("testQuorum", true, false, false, args);
    }

    /**
     * 定义Stream队列
     * @return
     */
    @Bean
    public Queue testStream() {
        Map<String, Object> args = new HashMap<String, Object>();
        args.put("x-queue-type", "stream");
        args.put("x-max-length-bytes",100_000_000); // 日志文件大小最多100M
        args.put("x-stream-max-segment-size", 1_000_000_000); // 每个小文件大小最多100M
        return new Queue("testStream", true, false, false, args);
    }

    /**
     * 定义交换机绑定队列
     * @return
     */
    @Bean
    public DirectExchange directExchange() {
        return new DirectExchange("directExchange");
    }

    @Bean
    public Binding bindingExchangeWithStream() {
        return BindingBuilder.bind(testStream()).to(directExchange()).with("log");
    }

    @Bean
    public Binding bindingExchangeWithQuorum() {
        return BindingBuilder.bind(testQuorum()).to(directExchange()).with("online");
    }




    //=================== fanout广播模式  ====================
    @Bean
    public Queue fanoutA(){
        return new Queue("fanout.a");
    }
    @Bean
    public Queue fanoutB(){
        return new Queue("fanout.b");
    }
    @Bean
    public Queue fanoutC(){
        return new Queue("fanout.c");
    }

    /**
     * 定义交换器
     * @return
     */
    @Bean
    FanoutExchange fanoutExchange(){
        // 定义一个名为fanoutExchange的fanout交换器
        return new FanoutExchange("fanoutExchange");

    }





    /**
     * 将定义的fanoutA队列与fanoutExchange交换机绑定
     * @return
     */
    @Bean
    public Binding bindingExchangeWithA() {
        return BindingBuilder.bind(fanoutA()).to(fanoutExchange());
    }
    /**
     * 将定义的fanoutB队列与fanoutExchange交换机绑定
     * @return
     */
    @Bean
    public Binding bindingExchangeWithB() {
        return BindingBuilder.bind(fanoutB()).to(fanoutExchange());
    }
    /**
     * 将定义的fanoutC队列与fanoutExchange交换机绑定
     * @return
     */
    @Bean
    public Binding bindingExchangeWithC() {
        return BindingBuilder.bind(fanoutC()).to(fanoutExchange());
    }



    //=================== topic主题模式  ====================
    @Bean
    public Queue topicA(){
        return new Queue("topic.a");
    }
    @Bean
    public Queue topicB(){
        return new Queue("topic.b");
    }
    @Bean
    public Queue topicC(){
        return new Queue("topic.c");
    }

    /**
     * 定义个topic交换机
     * @return
     */
    @Bean
    TopicExchange topicExchange(){
        // 定义一个名为topicExchange的topic交换机
        return new TopicExchange("topicExchange");
    }

    /**
     * 将定义的topicA队列与topicExchange交换机绑定
     * @return
     */
    @Bean
    public Binding bindingExchangeWithTopicA() {
        return BindingBuilder.bind(topicA()).to(topicExchange()).with("topic.msg");
    }

    /**
     * 将定义的topicB队列与topicExchange交换机绑定
     * *代表一个单词，比如MySQL、hot；#代表0个或多个单词
     * @return
     */
    @Bean
    public Binding bindingExchangeWithTopicB() {
        return BindingBuilder.bind(topicB()).to(topicExchange()).with("topic.#");
    }

    @Bean
    public Binding bindingExchangeWithTopicC() {
        return BindingBuilder.bind(topicC()).to(topicExchange()).with("topic.*.z");
    }

    //=================== Headers模式  ====================
    @Bean
    public Queue HeaderA(){
        return new Queue("HeaderA");
    }

    @Bean
    public Queue HeaderB(){
        return new Queue("HeaderB");
    }

    @Bean
    public HeadersExchange HeadersExchange(){
        return new HeadersExchange("HeadersExchange");
    }

    @Bean
    public Binding bindingExchangeWithHeaderA() {
        Map<String, Object> headers = new HashMap<>();
//        headers.put("x-match", "any");
        headers.put("log-level", "info");
        headers.put("bus-level", "product");
        headers.put("sys-level", "admin");

        return BindingBuilder.bind(HeaderA()).to(HeadersExchange()).whereAny(headers).match();
    }

    @Bean
    public Binding bindingExchangeWithHeaderB() {
        Map<String, Object> headers = new HashMap<>();
        headers.put("log-level", "error");
        headers.put("bus-level", "order");
        headers.put("sys-level", "admin");
        return BindingBuilder.bind(HeaderB()).to(HeadersExchange()).whereAny(headers).match();
    }

}
